package com.css.fxfzdzzh.modules.taskManage.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.css.fxfzdzzh.constants.FxfzConstants;
import com.css.fxfzdzzh.constants.YNEnum;
import com.css.fxfzdzzh.enums.DisasterTypeEnum;
import com.css.fxfzdzzh.enums.TaskEnum;
import com.css.fxfzdzzh.modules.sandLiquefaction.repository.SandLiquefactionRepository;
import com.css.fxfzdzzh.modules.spatialData.repository.entity.BoundaryEntity;
import com.css.fxfzdzzh.modules.spatialData.service.BoundaryService;
import com.css.fxfzdzzh.modules.taskManage.entity.TaskDistrictArea;
import com.css.fxfzdzzh.modules.taskManage.entity.TaskEntity;
import com.css.fxfzdzzh.modules.taskManage.repository.TaskRepository;
import com.css.fxfzdzzh.modules.taskManage.service.TaskService;
import com.css.fxfzdzzh.modules.taskManage.vo.TaskAreaExportVO;
import com.css.fxfzdzzh.modules.taskManage.vo.TaskQueryVO;
import com.css.fxfzdzzh.modules.taskManage.vo.TaskUpdateVO;
import com.css.fxfzdzzh.modules.taskManage.vo.TaskVO;
import com.css.fxfzdzzh.util.*;
import com.css.fxfzdzzh.web.PlatformSessionContext;
import com.css.fxfzdzzh.zcpt.sys.entity.SUser;
import com.css.fxfzdzzh.zcpt.sys.entity.common.page.Page;
import com.css.fxfzdzzh.zcpt.sys.service.SUserService;
import com.css.fxfzdzzh.zcpt.sys.service.SysAreaService;
import com.css.fxfzdzzh.zcpt.sys.service.SysRoleService;
import io.swagger.models.auth.In;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.swing.text.View;
import java.math.BigDecimal;
import java.rmi.server.ExportException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author Dbj
 * @date 2023年02月13日  14:11
 */
@Service
public class TaskServiceImpl implements TaskService {

    @Resource
    private TaskRepository taskRepository;

    @Resource
    SysAreaService sysAreaService;

    @Resource
    SysRoleService sysRoleService;

    @Resource
    SUserService sUserService;
    @Autowired
    BoundaryService boundaryService;

    @Resource
    @Qualifier("myTaskExecutor")
    private Executor executor;

    @Resource
    SandLiquefactionRepository sandLiquefactionRepository;

    /**
     * 数据源
     * 10.19.41.111
     */
    @Value("${spring.datasource.url}")
    private String url = "";
    @Value("${spring.datasource.username}")
    private String name = "";
    @Value("${spring.datasource.password}")
    private String pwd = "";
    /**
     * 保存任务
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveTask(TaskVO vo) throws Exception{
        TaskEntity taskEntity = vo.getTaskEntity();
        String userId =  PlatformSessionContext.getUserID();
        String taskId = UUIDGenerator.getUUID();
        String user = sUserService.getSUser(userId);
        SUser sUser = CreateGson.createGson().fromJson(user, SUser.class);
        taskEntity.setCreateUser(userId).setCreateTime(new Date())
        .setDtId(taskId).setTaskStatus(TaskEnum.ING.getState()+"")
        .setDelFlag(YNEnum.N.toString()).setCreateUserName(sUser.getUserName());
       /* Integer exist = taskRepository.findByTaskName(vo.getTaskEntity().getTaskName());
        if(exist>0){
            throw new RuntimeException("保存失败，存在相同名称的任务名称");
        }*/
        if(!PlatformObjectUtils.isEmpty(taskEntity.getRegionCodes())){
            String regionCodes = taskEntity.getRegionCodes();
            String[] split = regionCodes.split(",");
            List<String> regionCodeList = Arrays.asList(split);
            String boundaryCoordinate = boundaryService.getBoundaryCoordinate(regionCodeList);
            taskEntity.setTaskRegion(boundaryCoordinate);
        }
        taskRepository.saveTask(taskEntity);
        List<TaskDistrictArea> areaList = vo.getAreaList();
        if(PlatformObjectUtils.isNotEmpty(areaList)){
            AtomicInteger sno = new AtomicInteger(1);
            areaList.forEach(entity->{
                String tdaId = UUIDGenerator.getUUID();
                entity.setTdaId(tdaId).setDtId(taskId).setTdaName("区域"+sno.getAndIncrement());
                taskRepository.saveDistrictArea(entity);
            });
        }
    }

    @Override
    public Map<String, Object> getPage(TaskQueryVO taskVo, int curPage, int pageSize) {
        Long start = System.currentTimeMillis();
        String userId =  PlatformSessionContext.getUserID();
        taskVo.setCreateUser(userId);
        Map<String,Object> task=taskRepository.findTask(taskVo, curPage, pageSize);
        List<TaskEntity> tasks = (List<TaskEntity>) task.get("rows");
        Map<String,Object> statusMap = getStatusMap();
        Map<String,Object> typeMap = getDisasterType();
        for(TaskEntity entity:tasks){
            entity.setTaskStatus((String)statusMap.get(entity.getTaskStatus()));
            String disasterType = entity.getDisasterType();
            String[] split = new String[disasterType.length()];

            for (int i = 0; i < disasterType.length(); i++) {
                split[i] = String.valueOf(disasterType.charAt(i));
            }
            StringBuilder builder = new StringBuilder("");
            for (String s : split) {
                builder.append(typeMap.get(s)).append(",");
            }
            disasterType = builder.substring(0, builder.length() - 1);
            entity.setDisasterType(disasterType);
        }
        task.put("rows",tasks);
        System.out.println("查询时间:" + (System.currentTimeMillis() - start) / 1000);
        System.out.println(tasks.size());
        return task;
    }

    private Map<String, Object> getDisasterType() {
        Map<String,Object> map = new HashMap<>();
        map.put(DisasterTypeEnum.LANDSLIDE.getState()+"",DisasterTypeEnum.LANDSLIDE.getDesc());
        map.put(DisasterTypeEnum.LIQUEFACTION.getState()+"",DisasterTypeEnum.LIQUEFACTION.getDesc());
        map.put(DisasterTypeEnum.SUBSIDENCE.getState()+"",DisasterTypeEnum.SUBSIDENCE.getDesc());
        return map;
    }

    private Map<String, Object> getStatusMap() {
        Map<String,Object> map = new HashMap<>();
        map.put(TaskEnum.ING.getState()+"",TaskEnum.ING.getDesc());
        map.put(TaskEnum.REVIEWING.getState()+"",TaskEnum.REVIEWING.getDesc());
        map.put(TaskEnum.BACK.getState()+"",TaskEnum.BACK.getDesc());
        map.put(TaskEnum.END.getState()+"",TaskEnum.END.getDesc());
        return map;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(TaskUpdateVO vo) {
        vo.setUpdateUser(PlatformSessionContext.getUserID());
        vo.setUpdateTime(new Date());
        //开启子线程 删除沙土液化层次分析法中间过程产生的水系数据
        CompletableFuture.runAsync(() -> {
            sandLiquefactionRepository.deleteByTaskId(vo.getDtId());
        }, executor);
        taskRepository.update(vo);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(List<String> ids) {
        String userId =  PlatformSessionContext.getUserID();
        ids.forEach(id->{
            taskRepository.deleteAreaDataByTaskId(id);
            taskRepository.deleteTaskDataByTaskId(id,userId);
        });
    }
    @Override
    public TaskEntity getTaskWithOutGeom(String dtId){
        return taskRepository.getTaskWithOutGeom(dtId);
    }
    @Override
    public TaskEntity viewTask(String dtId) {
        TaskEntity taskEntity = taskRepository.viewTask(dtId);
        List<TaskDistrictArea> areaList = this.viewTaskArea(dtId);
        BigDecimal totalArea = new BigDecimal(0);
        if(PlatformObjectUtils.isNotEmpty(areaList)){
            for (TaskDistrictArea entity : areaList) {
                totalArea = totalArea.add(entity.getTdaArea());
            }
        }
        taskEntity.setArea(totalArea);
        String userId =  PlatformObjectUtils.isNotEmpty(PlatformSessionContext.getUserID())?PlatformSessionContext.getUserID():"80cd530287e54c6788925adf2dfc9da1";
        String user = sUserService.getSUser(userId);
        SUser sUser = CreateGson.createGson().fromJson(user, SUser.class);
        taskEntity.setCreateUser(userId).setCreateUserName(sUser.getUserName());

        return taskEntity;
    }

    @Override
    public List<TaskDistrictArea> viewTaskArea(String dtId) {
        return taskRepository.viewTaskArea(dtId);
    }

    @Override
    public void exportExcel(String dtId, HttpServletResponse response) throws Exception{
        List<TaskDistrictArea> taskDistrictAreas = this.viewTaskArea(dtId);
        if (taskDistrictAreas == null || taskDistrictAreas.size() <= 0) {
            throw new RuntimeException("数据为空,无法导出！");
        }
        TaskEntity taskEntity = this.viewTask(dtId);
        EasyPoiExcelUtil.exportExcel(taskDistrictAreas, taskEntity.getTaskName()+"各区域面积", taskEntity.getTaskName()+"各区域面积", TaskDistrictArea.class, taskEntity.getTaskName()+"各区域面积.xlsx", response);
    }

    @Override
    public String getTaskCode() {
        Calendar instance = Calendar.getInstance();
        String taskYear = String.valueOf(instance.get(Calendar.YEAR));
        DecimalFormat decimalFormat=new DecimalFormat("0000");
        String parentNum ="";
        StringBuilder str=new StringBuilder("");
        String userId =  PlatformSessionContext.getUserID();
        String role = sysRoleService.getRoleByUserId(userId);
        List<Map> roleMaps = JSONObject.parseArray(role, Map.class);
        for(Map roleMap:roleMaps){
            str.append(roleMap.get("roleCode")+",");
        }
        String roles = str.toString();

        String divisionCode = sysAreaService.getAreaCodeByUserId(userId);

        StringBuilder code=new StringBuilder("");

        StringBuilder stringBuilder = new StringBuilder("");
        stringBuilder.append(taskYear);

        divisionCode=divisionCode.substring(0,2);
        if(roles.contains(FxfzConstants.DZZH_COUN_YW_ROLE) || roles.contains(FxfzConstants.DZZH_COUN_GL_ROLE)){
            stringBuilder.append("00");
            code.append("00");
        }else {
            stringBuilder.append(divisionCode);
            code.append(divisionCode);
        }
        String maxParentNum=taskRepository.getMaxParentNum(taskYear,code.toString());
        if(PlatformObjectUtils.isEmpty(maxParentNum)){
            int i = 1;
            parentNum=decimalFormat.format(i);
        }else{
            String substring = maxParentNum.substring(7);
            parentNum = decimalFormat.format(Integer.parseInt(substring));
            int i=Integer.parseInt(parentNum)+1;
            return stringBuilder.append(decimalFormat.format(i)).toString();
        }

        return stringBuilder.append(parentNum).toString();
    }

    @Override
    public List<List<String>> queryProvinceCityCountyNameCodeListByGeomText(String geomText) {
        List<List<String>> resultList = new ArrayList<List<String>>();
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            if (!PlatformObjectUtils.isEmpty(geomText)) {
                conn = getConnection();
                List<String> nameList = new ArrayList<String>();//行政区划名称列表:省|市|区县|乡镇
                List<String> codeList = new ArrayList<String>();//行政区划编码列表:省|市|区县
                //查询行政区划
                String sql = "select c.name as province,c.code as code1,b.name as city,b.code as code2,a.name as county,a.code as code3 from district_boundary_county a " +
                        "left join district_boundary_city b on b.code=concat(subString(a.code,0,5),'00') " +
                        "left join district_boundary_province c on c.code=concat(subString(a.code,0,3),'0000')," +
                        "(select ST_GeometryFromText('"+geomText+"',4490) as geom) t " +
                        "where ST_Intersects(a.geom,t.geom) " +
                        "and ST_Touches(a.geom,t.geom)!='t' " +
                        "order by a.code,b.code,c.code;";
                ps = conn.prepareStatement(sql);
                rs = ps.executeQuery();
                while (rs.next()) {
                    String province = rs.getString("province");//行政区划名称--省
                    String city = rs.getString("city");//行政区划名称--市
                    String county = rs.getString("county");//行政区划名称--区县
                    if (!PlatformObjectUtils.isEmpty(province) && !PlatformObjectUtils.isEmpty(city) && !PlatformObjectUtils.isEmpty(county)){
                        String name = province + "-" + city + "-" + county;
                        nameList.add(name);//行政区划名称--省-市-区县
                        String code1 = rs.getString("code1");//行政区划编码--省
                        String code2 = rs.getString("code2");//行政区划编码--市
                        String code3 = rs.getString("code3");//行政区划编码--区县
                        String code = code1 + "-" + code2 + "-" + code3;
                        codeList.add(code);
                    }
                }
                if(nameList.size()>0){
                    resultList.add(nameList);//行政区划名称列表
                    resultList.add(codeList);//行政区划编码列表
                }
            }
        } catch (Exception e2) {
            e2.printStackTrace();
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
            try {
                if (ps != null) {
                    // 关闭连接
                    ps.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
            try {
                if (conn != null) {
                    conn.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }

        return resultList;
    }

    @Override
    public List<List<String>> queryProvinceNameCodeListByGeomText(String geomText) {
        List<List<String>> resultList = new ArrayList<List<String>>();
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            if (!PlatformObjectUtils.isEmpty(geomText)) {
                conn = getConnection();
                List<String> nameList = new ArrayList<String>();//行政区划名称列表:省
                List<String> codeList = new ArrayList<String>();//行政区划编码列表:省
                //查询行政区划
                String sql = "select c.name as province,c.code as code from district_boundary_province c," +
                        "(select ST_GeometryFromText('"+geomText+"',4490) as geom) t " +
                        "where ST_Intersects(c.geom,t.geom) " +
                        "and ST_Touches(c.geom,t.geom)!='t' " +
                        "order by c.code;";
                ps = conn.prepareStatement(sql);
                rs = ps.executeQuery();
                while (rs.next()) {
                    String province = rs.getString("province");//行政区划名称--省
                    if (!PlatformObjectUtils.isEmpty(province)){
                        String name = province;
                        nameList.add(name);//行政区划名称--省
                        String code = rs.getString("code");//行政区划编码--省
                        codeList.add(code);
                    }
                }
                if(nameList.size()>0){
                    resultList.add(nameList);//行政区划名称列表
                    resultList.add(codeList);//行政区划编码列表
                }
            }
        } catch (Exception e2) {
            e2.printStackTrace();
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
            try {
                if (ps != null) {
                    // 关闭连接
                    ps.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
            try {
                if (conn != null) {
                    conn.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }

        return resultList;
    }

    @Override
    public String queryGeomTextByProvinceCityCountyName(String province, String city, String county) {
        String geomText=null;
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            if (PlatformObjectUtils.isNotEmpty(province)) {
                conn = getConnection();
                //查询行政区划
                String sql = "";
                if (PlatformObjectUtils.isNotEmpty(city)){
                    if (PlatformObjectUtils.isNotEmpty(county)) {
                        sql = "select St_ASText(a.geom) geomText from district_boundary_county a " +
                                "left join district_boundary_city b on b.code=(subString(a.code,1,4) || '00') " +
                                "left join district_boundary_province c on c.code=(subString(a.code,1,2) || '0000')" +
                                "where c.name='" + province + "' and b.name='" + city + "' and a.name='" + county + "'";
                    }else {
                        sql = "select St_ASText(b.geom) geomText from district_boundary_city b " +
                                "left join district_boundary_province c on c.code=(subString(b.code,1,2) || '0000')" +
                                "where c.name='" + province + "' and b.name='" + city + "'";
                    }
                }else {
                    sql = "select St_ASText(c.geom) geomText from district_boundary_province c " +
                            "where c.name='" + province + "'";
                }
                    ps = conn.prepareStatement(sql);
                rs = ps.executeQuery();
                while (rs.next()) {
                    geomText = rs.getString("geomText");//行政区划名称--省
                }
            }
        } catch (Exception e2) {
            e2.printStackTrace();
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
            try {
                if (ps != null) {
                    // 关闭连接
                    ps.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
            try {
                if (conn != null) {
                    conn.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }

        return geomText;
    }

    /**
     * 获取数据库连接
     * SQL语句
     */
    private Connection getConnection() throws Exception {
        //Class.forName("com.mysql.cj.jdbc.Driver");
        Class.forName("org.postgresql.Driver");
        return DriverManager.getConnection(url, name, pwd);
    }

    @Override
    public List<TaskEntity> getTask() {
        String userId = PlatformSessionContext.getUserID();
        List<TaskEntity> parentTask=taskRepository.getAllTask(userId);
        return parentTask;
    }
}
